#pragma once
#ifndef __TESTBLOCKSET__H__
#define __TESTBLOCKSET__H__

#include "attest.h"

/*
	http://resrc.tistory.com/

	3489 	2349 	2489 	1 		2589 	589 	6 		7 		359
	3789 	1239 	2789 	23789 	25789 	6 		23589 	23589 	4
	36789 	2369 	5 		4 		2789 	789 	1 		2389 	39
	479 	8 		3 		79 		6 		14579 	59 		1459 	2
	5 		2469 	2479 	279 	12479 	1479 	39 		1349 	8
	1 		249 	249 	289 	3 		4589 	7 		6 		59
	89 		59 		1 		6789 	789 	3 		4 		2589 	5679
	2 		349 	489 	5 		14789 	14789 	389 	1389 	13679
	3489 	7 		6 		89 		1489 	2 		3589 	13589 	1359

*/

class BlockSetTestCase : public TestCase
{
public:
	BlockSetTestCase(const Char* pszName) : TestCase(pszName)
	{
		Add(NEW_TEST(BlockSetTestCase::TestUpdateCandidate));
		Add(NEW_TEST(BlockSetTestCase::TestUpdateCandidate1));
		Add(NEW_TEST(BlockSetTestCase::TestUpdateCandidate2));
		Add(NEW_TEST(BlockSetTestCase::TestUpdateCandidate3));
	}

	virtual Bool SetUp()
	{
		aBoard_.CreateCell(9, 9);

		ATASSERT(aBoard_.Set(3, 1));
		ATASSERT(aBoard_.Set(6, 6));
		ATASSERT(aBoard_.Set(7, 7));
		ATASSERT(aBoard_.Set(14, 6));
		ATASSERT(aBoard_.Set(17, 4));
		ATASSERT(aBoard_.Set(20, 5));
		ATASSERT(aBoard_.Set(21, 4));
		ATASSERT(aBoard_.Set(24, 1));
		ATASSERT(aBoard_.Set(28, 8));
		ATASSERT(aBoard_.Set(29, 3));
		ATASSERT(aBoard_.Set(31, 6));
		ATASSERT(aBoard_.Set(35, 2));
		ATASSERT(aBoard_.Set(36, 5));
		ATASSERT(aBoard_.Set(44, 8));
		ATASSERT(aBoard_.Set(45, 1));
		ATASSERT(aBoard_.Set(49, 3));
		ATASSERT(aBoard_.Set(51, 7));
		ATASSERT(aBoard_.Set(52, 6));
		ATASSERT(aBoard_.Set(56, 1));
		ATASSERT(aBoard_.Set(59, 3));
		ATASSERT(aBoard_.Set(60, 4));
		ATASSERT(aBoard_.Set(63, 2));
		ATASSERT(aBoard_.Set(66, 5));
		ATASSERT(aBoard_.Set(73, 7));
		ATASSERT(aBoard_.Set(74, 6));
		ATASSERT(aBoard_.Set(78, 2));

		ATASSERT(aBoard_.UpdateAllCandidate());
		return True;
	}

	virtual Bool TearDown()
	{
		return aBoard_.DestroyCell();
	}


	int TestUpdateCandidate()
	{
		const ATSudokuEngine::Cell* pCell = aBoard_.At(10);

		ATSudokuEngine::CandidateConstIterator itStart = pCell->BeginCandidates();
		ATSudokuEngine::CandidateConstIterator itEnd = pCell->EndCandidates();

		ATASSERT(itStart != itEnd);
		ATASSERT(*itStart++ == 1);
		ATASSERT(*itStart++ == 2);
		ATASSERT(*itStart++ == 3);
		ATASSERT(*itStart++ == 9);
		ATASSERT(itStart == itEnd);

		return 0;
	}

	int TestUpdateCandidate1()
	{
		const ATSudokuEngine::Cell* pCell = aBoard_.At(37);

		ATSudokuEngine::CandidateConstIterator itStart = pCell->BeginCandidates();
		ATSudokuEngine::CandidateConstIterator itEnd = pCell->EndCandidates();


		ATASSERT(itStart != itEnd);
		ATASSERT(*itStart++ == 2);
		ATASSERT(*itStart++ == 4);
		ATASSERT(*itStart++ == 6);
		ATASSERT(*itStart++ == 9);
		ATASSERT(itStart == itEnd);

		return 0;
	}

	int TestUpdateCandidate2()
	{
		const ATSudokuEngine::Cell* pCell = aBoard_.At(71);

		ATSudokuEngine::CandidateConstIterator itStart = pCell->BeginCandidates();
		ATSudokuEngine::CandidateConstIterator itEnd = pCell->EndCandidates();

		ATASSERT(itStart != itEnd);
		ATASSERT(*itStart++ == 1);
		ATASSERT(*itStart++ == 3);
		ATASSERT(*itStart++ == 6);
		ATASSERT(*itStart++ == 7);
		ATASSERT(*itStart++ == 9);
		ATASSERT(itStart == itEnd);

		return 0;
	}

	int TestUpdateCandidate3()
	{
		const ATSudokuEngine::Cell* pCell = aBoard_.At(79);

		ATSudokuEngine::CandidateConstIterator itStart = pCell->BeginCandidates();
		ATSudokuEngine::CandidateConstIterator itEnd = pCell->EndCandidates();

		ATASSERT(itStart != itEnd);
		ATASSERT(*itStart++ == 1);
		ATASSERT(*itStart++ == 3);
		ATASSERT(*itStart++ == 5);
		ATASSERT(*itStart++ == 8);
		ATASSERT(*itStart++ == 9);
		ATASSERT(itStart == itEnd);

		return 0;
	}

protected:
	ATSudokuEngine::Board aBoard_;
};


#endif